﻿using FlyingEye.EntityFrameworkCore;
using FlyingEye.Users;
using FlyingEye.Users.Exceptions;
using FlyingEye.Users.Models;
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;

namespace FlyingEye.Repositories
{
    public class UserRepository : EfCoreRepository<MySqlDbContext, UserModel, Guid>, IUserRepository
    {
        public UserRepository(IDbContextProvider<MySqlDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public async Task AddUserAsync(UserModel userModel)
        {
            var user = await this.FindAsync(userItem => userItem.Id == userModel.Id);

            if (user != null)
            {
                throw new UserAlreadyExistsException($"用户 ID {userModel.Id} 已存在。");
            }

            user = await this.FindAsync(userItem => userItem.UserName == userModel.UserName);

            if (user != null)
            {
                throw new UserAlreadyExistsException($"用户 {userModel.UserName} 已存在。");
            }

            (await this.GetDbSetAsync()).Add(userModel);

            await this.SaveChangesAsync(CancellationToken.None);
        }

        public async Task UpdateUserAsync(UserModel userModel)
        {
            var user = await this.FindAsync(userItem => userItem.Id == userModel.Id);

            if (user == null)
            {
                throw new UserNotExistException($"用户 ID {userModel.Id} 不存在。");
            }

            // 根据用户名查找相同的用户
            var otherUser = await this.FindAsync(userItem => userItem.UserName == userModel.UserName);

            // 如果用户名已经被占用
            if (otherUser.Id != userModel.Id)
            {
                throw new UserAlreadyExistsException($"用户名 {otherUser.UserName} 已存在。");
            }

            await this.UpdateAsync(userModel, true);
        }

        public async Task DeleteUserAsync(UserModel userModel)
        {
            var user = await this.FindAsync(userItem => userItem.Id == userModel.Id);

            if (user == null)
            {
                throw new UserNotExistException($"用户 ID {userModel.Id} 不存在。");
            }

            await this.DeleteAsync(userModel, true);
        }

        /// <summary>
        /// 根据用户名删除用户
        /// </summary>
        /// <param name="name">用户名</param>
        /// <returns></returns>
        /// <exception cref="UserNotExistException">用户不存在异常</exception>
        public async Task DeleteUserByNameAsync(string name)
        {
            var user = await GetUserByNameAsync(name);

            if (user == null)
            {
                throw new UserNotExistException($"用户 {name} 不存在。");
            }

            await DeleteUserAsync(user);
        }

        /// <summary>
        /// 根据用户名获取用户信息，如果存在多个用户，则抛出异常 <see cref="InvalidOperationException"/>
        /// </summary>
        public async Task<UserModel?> GetUserByNameAsync(string userName)
        {
            return await this.FindAsync(userItem => userItem.UserName == userName);
        }
    }
}
